# 作者： 李泉志
# 2025年01月05日12时58分秒
# 2947029073@qq.com
"""
变量和数据是分开存储的
数据保存在内存中的一个位置
变量中保存着数据在内存中的地址——这是重点
变量中记录数据的地址，就叫做引用
使用id() 函数可以查看变量中保存数据所在的内存地址

注意：如果变量已经被定义，当给一个变量赋值的时候，本质上是修改了数据的引用
变量不再对之前的数据引用
变量改为对新赋值的数据引用
"""


def func1():
    a = 1
    b = 1
    print(id(a), '=', id(b))  # a,b地址相同
    c = a
    a = 2
    print(id(a), '!=', id(c))  # a改变后a,c地址不同


# func1()
"""
函数的 实参/返回值 都是是靠 引用 来传递来的
"""


def test(num):
    print(f'num的地址是{id(num)}')
    result = 100
    print(f'result的地址是{id(result)}')
    return result


def test_test():
    a = 10
    print(f'调用前a的地址是{id(a)}')
    r = test(a)
    print(f'调用后a的地址是{id(a)}')
    print(f'调用后r的地址是{id(r)}')


# test_test()
"""
• 不可变类型，内存中的数据不允许被修改：
    – 数字类型 int, bool, float, complex
    – 字符串 str
    – 元组 tuple
    不可以实现在被调函数内去修改调用函数内的某个变量值
• 可变类型，内存中的数据可以被修改：
    – 列表 list
    – 字典 dict
    – 集合 set
    注意：字典的 key 只能使用不可变类型的数据
通过接口改变的是数据所在的位置，变量的地址没变
1. 可变类型的数据变化，是通过 方法 来实现的
2. 如果给一个可变类型的变量，赋值了一个新的数据，引用会修改
– 变量不再对之前的数据引用
– 变量改为对新赋值的数据引用
"""


def change1(new_list):  # list未改变，不能这样赋值改变可变数据类型
    new_list = [4, 5, 6]


def change2(new_list):  # list改变
    new_list[0] = 10


def test_change():
    my_list = [1, 2, 3]  # 可变数据类型
    # chang  e1(my_list)
    change2(my_list)
    print(my_list)


# test_change()

"""
• 局部变量是在函数内部定义的变量，只能在函数内部使用
• 全局变量是在函数外部定义的变量（没有定义在某一个函数内），所有函数内部都可以使用这个变量
提示：在其他的开发语言中，大多不推荐使用全局变量 —— 可变范围太大，导致程序不好维护
"""

"""
局部变量：
• 函数执行结束后，函数内部的局部变量，会被系统回收
• 不同的函数，可以定义相同的名字的局部变量，但是彼此之间不会产生影响
• 作用：在函数内部使用，临时保存函数内部需要使用的数据
局部变量的生命周期
• 生命周期就是变量从被创建到被系统回收的过程
• 局部变量在函数执行时才会被创建
• 函数执行结束后局部变量被系统回收
• 局部变量在生命周期内，可以用来存储函数内部临时使用到的数据
"""

"""
全局变量：
1) 函数不能直接修改全局变量的引用
• 全局变量是在函数外部定义的变量，所有函数内部都可以使用这个变量
• 在函数内部，可以通过全局变量的引用获取对应的数据
• 但是，不允许直接修改全局变量的引用 —— 使用赋值语句修改全局变量的值
2) 在函数内部修改全局变量的值
• 如果在函数中需要修改全局变量，需要使用 global 进行声明
3) 全局变量定义的位置
• 为了保证所有的函数都能够正确使用到全局变量，应该将全局变量定义在其他函数（调用）的上方
4) 全局变量命名的建议
• 为了避免局部变量和全局变量出现混淆，在定义全局变量时，会有一些开发要求，例如：
• 全局变量名前应该增加 g_ 或者 gl_ 的前缀
"""


def demo1():
    print(num)


# demo1()
num = 10  # num在demo1定义下面也可以执行，但在调用demo1下面会报错

"""
注意：函数执行时，需要处理变量时会：
1. 首先查找函数内部是否存在指定名称的局部变量，如果有，直接使用
2. 如果没有，查找函数外部是否存在指定名称的全局变量，如果有，直接使用
3. 如果还没有，程序报错！
"""


def demo2():  # 第一个num在函数内没找到认为是全局变量
    global a  # 提前声明num为全局变量就可以修改
    print(a)
    a = 2  # 此后修改num认为改变全局变量报错
    print(f'修改后{a}')

a = 10
# demo2()
